// src/main.rs
use std::{cell::RefCell, ffi::CString, os::fd::AsRawFd, rc::Rc, sync::Arc};

use dirs::font_dir;
use font_kit::{family_name::FamilyName, properties::Properties, source::SystemSource};
use glyphon::{
    Attrs, Buffer, Color, FontSystem, HorizontalAlign, Layout, TextArea, TextBounds, VerticalAlign,
};
use libc::{dup2, execvp, fork, setsid, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
use pty::Pty;
use signal_hook::{consts::SIGWINCH, iterator::Signals};
use termios::Termios;
use tokio::{
    io::{AsyncReadExt, AsyncWriteExt},
    sync::mpsc,
};
use vte::{Params, Parser, Perform};
use wgpu::{
    CommandEncoderDescriptor, CompositeAlphaMode, Device, DeviceDescriptor, Features, Instance,
    Limits, LoadOp, PresentMode, Queue, RenderPassColorAttachment, RenderPassDescriptor,
    RequestAdapterOptions, Surface, SurfaceConfiguration, SurfaceTexture, TextureViewDescriptor,
};
use winit::{
    event::{Event, KeyEvent, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::Window,
};

// ======================== 核心枚举：跨层消息 ========================
#[derive(Debug)]
enum TerminalEvent {
    // PTY 输出（子进程的stdout/stderr）
    PtyOutput(Vec<u8>),
    // 窗口大小变更（行/列）
    WindowResize(u16, u16),
    // 键盘输入（需写入PTY）
    KeyInput(Vec<u8>),
}

// ======================== 终端状态：由vte维护 ========================
#[derive(Debug, Default)]
struct TerminalState {
    // 终端画布：行 × 列 → (字符, 前景色, 背景色)
    grid: Vec<Vec<(char, [f32; 4], [f32; 4])>>,
    // 光标位置（行/列）
    cursor: (usize, usize),
    // 终端尺寸（行/列）
    size: (usize, usize),
}

// 实现vte的Perform trait：解析ANSI序列后更新终端状态
impl Perform for TerminalState {
    fn print(&mut self, c: char) {
        // 简化版：打印字符到当前光标位置
        let (row, col) = self.cursor;
        if row < self.size.0 && col < self.size.1 {
            self.grid[row][col] = (c, [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 1.0]);
            // 光标右移
            self.cursor.1 += 1;
            if self.cursor.1 >= self.size.1 {
                self.cursor.1 = 0;
                self.cursor.0 += 1;
            }
        }
    }

    // 需实现更多Perform方法（光标移动、颜色、清屏等），这里先简化
    fn execute(&mut self, _: u8) {}
    fn hook(&mut self, _: &[u8], _: &[u8], _: bool) {}
    fn put(&mut self, _: u8) {}
    fn unhook(&mut self) {}
    fn osc_dispatch(&mut self, _: &[&[u8]], _: bool) {}
    fn csi_dispatch(&mut self, _: &Params, _: &[u8], _: bool, _: char) {}
    fn esc_dispatch(&mut self, _: &[u8], _: &[u8], _: bool, _: char) {}
}

// ======================== PTY 管理：异步读写 ========================
async fn init_pty(
    tx: mpsc::Sender<TerminalEvent>,
    initial_rows: u16,
    initial_cols: u16,
) -> std::io::Result<Pty> {
    // 1. 创建PTY
    let mut pty = Pty::new()?;
    let slave_fd = pty.slave()?;

    // 2. 设置PTY初始尺寸
    pty.set_window_size(initial_cols, initial_rows)?;

    // 3. Fork子进程（Unix核心）
    unsafe {
        match fork() {
            -1 => {
                return Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    "fork failed",
                ))
            }
            0 => {
                // 子进程：脱离父进程、重定向标准IO到PTY
                setsid(); // 创建新会话
                dup2(slave_fd.as_raw_fd(), STDIN_FILENO);
                dup2(slave_fd.as_raw_fd(), STDOUT_FILENO);
                dup2(slave_fd.as_raw_fd(), STDERR_FILENO);

                // 启动系统默认Shell（bash/zsh/fish）
                let shell = CString::new(std::env::var("SHELL").unwrap_or("bash".into()))?;
                execvp(shell.as_ptr(), std::ptr::null());

                // execvp失败才会执行到这里
                return Err(std::io::Error::new(
                    std::io::ErrorKind::Other,
                    "execvp failed",
                ));
            }
            _ => {} // 父进程：继续管理PTY
        }
    }

    // 4. 异步读取PTY输出（子进程的stdout/stderr）
    let mut pty_reader = pty.reader()?;
    tokio::spawn(async move {
        let mut buf = [0u8; 1024];
        loop {
            match pty_reader.read(&mut buf).await {
                Ok(0) => break, // EOF
                Ok(n) => {
                    let data = buf[..n].to_vec();
                    // 发送PTY输出到UI层
                    let _ = tx.send(TerminalEvent::PtyOutput(data)).await;
                }
                Err(e) => {
                    eprintln!("PTY read error: {}", e);
                    break;
                }
            }
        }
    });

    Ok(pty)
}

// ======================== 渲染初始化：WGPU+Glyphon ========================
struct RenderContext {
    instance: Instance,
    surface: Surface,
    device: Device,
    queue: Queue,
    config: SurfaceConfiguration,
    font_system: FontSystem,
    text_area: TextArea,
    window: Arc<Window>,
}

impl RenderContext {
    fn new(window: Arc<Window>) -> Self {
        // 1. WGPU实例+表面初始化
        let instance = Instance::new(wgpu::InstanceDescriptor::default());
        let surface = unsafe { instance.create_surface(&window) }.unwrap();
        let adapter = pollster::block_on(instance.request_adapter(&RequestAdapterOptions {
            power_preference: wgpu::PowerPreference::HighPerformance,
            compatible_surface: Some(&surface),
            force_fallback_adapter: false,
        }))
        .unwrap();

        // WGPU 设备请求
        let (device, queue) = pollster::block_on(adapter.request_device(
            &wgpu::DeviceDescriptor {
                required_features: wgpu::Features::empty(),
                required_limits: wgpu::Limits::default(),
                // 新增必填字段（全部用默认值）
                experimental_features: wgpu::ExperimentalFeatures::empty(),
                memory_hints: wgpu::MemoryHints::Performance, // 终端渲染优先性能
                trace: None,                                  // 关闭 trace（生产环境用 None）
                // 保留原 label
                label: Some("WGPU Device"),
            },
            None, // 无 trace 回调
        ))
        .unwrap();

        let surface_caps = surface.get_capabilities(&adapter);
        let surface_format = surface_caps
            .formats
            .iter()
            .find(|f| f.is_srgb())
            .copied()
            .unwrap_or(surface_caps.formats[0]);

        let config = SurfaceConfiguration {
            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
            format: surface_format,
            width: window.inner_size().width,
            height: window.inner_size().height,
            present_mode: PresentMode::AutoVsync,
            alpha_mode: CompositeAlphaMode::Auto,
            view_formats: vec![],
            desired_maximum_frame_latency: 2,
        };
        surface.configure(&device, &config);

        // 2. 加载系统等宽字体
        let mut font_system = FontSystem::new();
        let system_source = SystemSource::new();
        // 优先加载的等宽字体列表（Linux/macOS适配）
        let font_families = [
            FamilyName::Title("DejaVu Sans Mono"), // Linux
            FamilyName::Title("Monaco"),           // macOS
            FamilyName::Title("Courier New"),      // 兜底
        ];

        let font = font_families
            .iter()
            .find_map(|family| {
                system_source
                    .select_best_match(&[family.clone()], &Properties::new())
                    .ok()
            })
            .unwrap();

        // 3. Glyphon文本渲染配置
        let mut text_area = TextArea::new(&mut font_system, font)
            .with_size(14.0) // 字体大小
            .with_color(Color::rgb(1.0, 1.0, 1.0)) // 默认白色
            .with_align(HorizontalAlign::Left, VerticalAlign::Top);

        Self {
            instance,
            surface,
            device,
            queue,
            config,
            font_system,
            text_area,
            window,
        }
    }

    // 渲染终端内容
    fn render(&mut self, state: &TerminalState) {
        // 1. 准备渲染表面
        let frame: wgpu::SurfaceTexture = match self.surface.get_current_texture() {
            Ok(f) => f,
            Err(e) => {
                eprintln!("Failed to get surface texture: {}", e);
                return;
            }
        };
        let view = frame
            .texture
            .create_view(&wgpu::TextureViewDescriptor::default());

        // 2. 构建终端文本（简化版：拼接所有字符）
        let mut terminal_text = String::new();
        for row in &state.grid {
            for (c, _, _) in row {
                terminal_text.push(*c);
            }
            terminal_text.push('\n');
        }
        self.text_area
            .set_text(&mut self.font_system, &terminal_text);

        // 3. 编码渲染指令
        let mut encoder = self
            .device
            .create_command_encoder(&wgpu::CommandEncoderDescriptor {
                label: Some("Render Encoder"),
            });

        // ========== 修正后的渲染通道配置 ==========
        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
            label: Some("Render Pass"),
            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                view: &view,
                resolve_target: None,
                ops: wgpu::Operations {
                    load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
                    store: true,
                },
                depth_slice: None, // 新增：2D渲染无需深度切片
            })],
            depth_stencil_attachment: None,
            timestamp_writes: None,    // 新增：禁用时间戳写入
            occlusion_query_set: None, // 新增：禁用遮挡查询
        });
        // =========================================

        // 4. Glyphon渲染文本（修正 TextBounds 字段）
        glyphon::render_text(
            &mut render_pass,
            &mut self.font_system,
            &mut self.swash_cache,
            &mut self.text_area,
            &glyphon::Resolution {
                width: self.config.width,
                height: self.config.height,
            },
            glyphon::TextBounds {
                left: 0.0,                         // 对应原 x: 0.0
                top: 0.0,                          // 对应原 y: 0.0
                right: self.config.width as f32,   // left + width
                bottom: self.config.height as f32, // top + height
            },
        );

        drop(render_pass);
        self.queue.submit(std::iter::once(encoder.finish()));
        frame.present();
    }

    // 窗口大小变更时更新渲染配置
    fn resize(&mut self, width: u32, height: u32) {
        if width > 0 && height > 0 {
            self.config.width = width;
            self.config.height = height;
            self.surface.configure(&self.device, &self.config);
        }
    }
}

// ======================== 主函数：整合所有模块 ========================
#[tokio::main]
async fn main() -> std::io::Result<()> {
    // 1. 初始化Winit事件循环+窗口
    let event_loop = EventLoop::new();
    let window = Arc::new(
        winit::window::WindowBuilder::new()
            .with_title("Rust Terminal")
            .with_inner_size(winit::dpi::LogicalSize::new(800, 600))
            .build(&event_loop)
            .unwrap(),
    );

    // 2. 初始化通信通道（异步→UI）
    let (tx, mut rx) = mpsc::channel::<TerminalEvent>(100);
    let tx_clone = tx.clone();

    // 3. 初始化终端状态（默认80列×24行）
    let initial_cols = 80;
    let initial_rows = 24;
    let terminal_state = Rc::new(RefCell::new(TerminalState {
        grid: vec![vec![(' ', [1.0; 4], [0.0; 4]); initial_cols]; initial_rows],
        cursor: (0, 0),
        size: (initial_rows as usize, initial_cols as usize),
    }));

    // 4. 初始化PTY（启动Shell）
    let mut pty = init_pty(tx_clone, initial_rows, initial_cols).await?;

    // 5. 初始化渲染上下文
    let mut render_ctx = RenderContext::new(window.clone());

    // 6. 监听SIGWINCH信号（窗口大小变更）
    let mut signals = Signals::new(&[SIGWINCH])?;
    let tx_sig = tx.clone();
    tokio::spawn(async move {
        for sig in signals.forever() {
            if sig == SIGWINCH {
                // 获取当前窗口的终端行列数（简化版：按字体大小计算）
                let cols = 80; // 实际需按窗口宽度/字体宽度计算
                let rows = 24; // 实际需按窗口高度/字体高度计算
                let _ = tx_sig.send(TerminalEvent::WindowResize(rows, cols)).await;
            }
        }
    });

    // 7. 运行Winit事件循环
    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Poll;

        // 处理异步消息（PTY输出/窗口大小变更）
        while let Ok(Some(event)) = rx.try_recv() {
            match event {
                TerminalEvent::PtyOutput(data) => {
                    // 解析PTY输出的ANSI序列→更新终端状态
                    let mut parser = Parser::new();
                    let mut state = terminal_state.borrow_mut();
                    for byte in data {
                        parser.advance(&mut *state, byte);
                    }
                }
                TerminalEvent::WindowResize(rows, cols) => {
                    // 更新PTY窗口尺寸
                    let _ = pty.set_window_size(cols, rows);
                    // 更新终端状态尺寸
                    let mut state = terminal_state.borrow_mut();
                    state.size = (rows as usize, cols as usize);
                    state.grid =
                        vec![vec![(' ', [1.0; 4], [0.0; 4]); cols as usize]; rows as usize];
                }
                TerminalEvent::KeyInput(data) => {
                    // 键盘输入→写入PTY
                    let mut pty_writer = pty.writer().unwrap();
                    tokio::spawn(async move {
                        let _ = pty_writer.write_all(&data).await;
                    });
                }
            }
        }

        // 处理窗口事件
        match event {
            Event::WindowEvent { event, .. } => match event {
                WindowEvent::CloseRequested => {
                    *control_flow = ControlFlow::Exit;
                }
                WindowEvent::Resized(size) => {
                    // 更新渲染尺寸
                    render_ctx.resize(size.width, size.height);
                }
                WindowEvent::KeyboardInput { event, .. } => {
                    // 简化版：键盘输入→转为字节发送到PTY
                    if let KeyEvent {
                        text: Some(text), ..
                    } = event
                    {
                        let _ = tx.try_send(TerminalEvent::KeyInput(text.as_bytes().to_vec()));
                    }
                }
                _ => {}
            },
            // 渲染帧
            Event::RedrawRequested(_) => {
                render_ctx.render(&terminal_state.borrow());
            }
            // 初始渲染
            Event::NewEvents(_) => {
                window.request_redraw();
            }
            _ => {}
        }
    });
}
